﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SimpleModeler.Graphics;
using System.Reflection;

namespace SimpleModeler.GUI
{
    /// <summary>
    /// ToolBar-Hauptfenster
    /// </summary>
    public partial class EditWindow : Form
    {
        #region Properties
        private Toolbar _toolbar;
        private SceneObject _selectedObj;
        private EditObjectWindow _editObjectWindow;
        private Dictionary<string, Type> _types = new Dictionary<string, Type>();
        #endregion // Properties

        
        #region Constructors
        /// <summary>
        /// Konstruktor
        /// </summary>
        /// <param name="toolbar">ToolBar</param>
        /// <param name="selectedObj">Selektiertes Objekt</param>
        public EditWindow(Toolbar toolbar, SceneObject selectedObj)
        {
            InitializeComponent();

            Type sct = typeof(SceneObject);
            foreach (var t in Assembly.GetCallingAssembly().GetTypes())
            {
                if(sct.IsAssignableFrom(t) && t.IsClass && !t.IsAbstract)
                {
                    _types.Add(t.Name, t);
                }
            }

            foreach(var i in _types)
            {
                this.lvTypes.Items.Add(new ListViewItem(i.Key));
            }


            this._editObjectWindow = new EditObjectWindow();
            SetSelected(selectedObj);
            this._toolbar = toolbar;
        }
        #endregion // Constructors


        #region Methods
        #region EventHandler
        private void butDeleteObj_Click(object sender, EventArgs e)
        {
            this.Delete(this._selectedObj.ID);
        }

        private void butEditObj_Click(object sender, EventArgs e)
        {
            if (!_editObjectWindow.IsDisposed)
                _editObjectWindow.Obj = this._selectedObj;
            else
                this._editObjectWindow = new EditObjectWindow(this._selectedObj);

            if(!this._editObjectWindow.Visible)
                this._editObjectWindow.Show(this);
        }

        private void ButAdd_Click(object sender, EventArgs e)
        {
            if (this.lvTypes.SelectedItems.Count == 1)
            {
                string key = this.lvTypes.SelectedItems[0].Text;
                if (this._types.ContainsKey(key))
                    _toolbar.Add(this._types[key]);
            }
        }

        private void lvTypes_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.ButAdd.Enabled = lvTypes.SelectedItems.Count != 0;
        }

        private void butHelp_Click(object sender, EventArgs e)
        {
            HelpWindow hw = new HelpWindow();
            hw.ShowDialog();
        }
        #endregion // EventHandler


        #region Manipulations-Methods
        /// <summary>
        /// Hebt die Selektierung auf
        /// </summary>
        public void Unselect() { SetSelected(null); }

        /// <summary>
        /// Setzt die Selektierung auf das angegebene Objekt
        /// </summary>
        /// <param name="so">Zu selektierendes Objekt</param>
        public void Select(SceneObject so) { SetSelected(so); }

        /// <summary>
        /// Löscht das Objekt mit der angegebenen ID
        /// </summary>
        /// <param name="id">ID des zu löschenden Objektes</param>
        public void Delete(ID id)
        {
            _toolbar.Delete(id);
            SetSelected(null);
        }

        /// <summary>
        /// Fügt das angegebene Objekt in die Szene ein
        /// </summary>
        /// <param name="so">Neues Objekt</param>
        public void Add(SceneObject so) { _toolbar.Add(so, false); }

        /// <summary>
        /// Ändert das angegebene Objekt
        /// </summary>
        /// <param name="so">Das zu ändernde Objekt</param>
        public void Edit(SceneObject so) { _toolbar.Edit(so); }
        #endregion // Manipulations-Methods


        /// <summary>
        /// Setzt die Selektion im aktuellen Kontext
        /// </summary>
        /// <param name="selectedObj"></param>
        private void SetSelected(SceneObject selectedObj)
        {
            this._selectedObj = selectedObj;
            this.lblSelObjName.Text = selectedObj == null ? "Keines" : selectedObj.ToString();
            this.grpSelectedObj.Enabled = selectedObj != null;
            _editObjectWindow.Obj = this._selectedObj;
        }

        /// <summary>
        /// Schließt das Window und alle dazugehörigen
        /// </summary>
        public void CloseWindow()
        {
            if (this._editObjectWindow != null || this._editObjectWindow.IsDisposed)
                this._editObjectWindow.Close();
            this.Close();
        }
        #endregion // Methods
    }
}
